package com.guodi.map.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guodi.common.utils.PageData;
import com.guodi.core.secure.LoginUser;
import com.guodi.map.entity.MapFunctionDir;
import com.guodi.map.mapper.MapFunctionDirMapper;
import com.guodi.map.service.IMapFunctionDirService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @描述：地图功能模块目录/图层表 服务类
 * @作者: 代鹏刚
 * @日期: 2019-12-13
 */
@Service
public class MapFunctionDirServiceImpl extends ServiceImpl<MapFunctionDirMapper, MapFunctionDir> implements IMapFunctionDirService {
    @Resource
    private MapFunctionDirMapper mapFunctionDirMapper;


    /**
     * @描述: 修改功能参数图层的状态，如果传回的是目录节点id，则会将该目录下所有功能参数状态（status）都改成1；如果传回的是功能参数节点id，则仅修改当前功能参数图层的状态（status）为1。
     *          其余未选中的功能参数图层状态（status）统一置为0
     * @入参: functionCode 功能模块的功能编码，非空必填
     * @入参: selectFunDirIds 选中的id列表，可以是目录的id，也可以是功能参数图层的id，非空必填
     * @入参: user 当前用户，非空必填
     * @出参:
     * @作者: 陈宏成
     * @日期: 2021-03-16
     **/
    @Transactional
    @Override
    public void updateStatus(String functionCode, List<String>  selectFunDirIds, LoginUser user){
        String[] roleIdsStr = user.getRoleId().split(",");
        // 先获取该功能模块的全部节点
        List<MapFunctionDir> functionDirs = this.getFunctionDirByRoleId(functionCode, Arrays.asList(roleIdsStr));
        // 需要更新的功能参数图层列表
        List<MapFunctionDir> updateFunDirList = new LinkedList<>();
        // 遍历修改status变量为默认
        for(MapFunctionDir functionDir : functionDirs) {
            if (selectFunDirIds.contains(functionDir.getId())){
                if(functionDir.getType() == 1){
                    // 如果是目录，则需要将其子节点全部查出，并修改所有功能参数图层
                    List<MapFunctionDir> childDir = this.filterChildFromList(functionDirs, functionDir.getId());
                    childDir = childDir.stream().filter(dir->dir.getType() == 2).map(dir->{
                        // 修改成默认状态
                        dir.setStatus(1);
                        return dir;
                    }).collect(Collectors.toList());
                    // 全部添加到更新列表中
                    updateFunDirList.addAll(childDir);
                }else{
                    // 如果直接就是功能参数图层，就直接修改成默认状态
                    functionDir.setStatus(1);
                    // 添加到更新列表中
                    updateFunDirList.add(functionDir);
                }
            }
        }
        // 从全部functionDir中获取type==2的功能参数图层
        List<MapFunctionDir> functionList = functionDirs.stream().filter(dir -> dir.getType() == 2).collect(Collectors.toList());
        // 将设置成默认状态的节点全部去除，剩余的功能参数图层就是要置为非默认（即0）
        functionList.removeAll(updateFunDirList);
        functionList.forEach(dir->{
            dir.setStatus(0);
        });
        // 全部添加到更新列表
        updateFunDirList.addAll(functionList);
        // 统一修改更新人和更新时间
        updateFunDirList.forEach(functionDir->{
            functionDir.setModifier(user.getUserId().toString());
            functionDir.setModifyTime(new Date());
            //防止误修改
            functionDir.setCreator(null);
            functionDir.setCreateTime(null);
        });
        // 批量更新
        this.updateBatchById(updateFunDirList);
    }

    /**
     * 从list列表中找出指定节点的所有子节点
     * @入参: dataList
     * @入参: parentId
     * @出参: 指定节点的所有子节点
     */
    private List<MapFunctionDir> filterChildFromList(List<MapFunctionDir> dataList, String parentId){
        // 创建结果
        LinkedList<MapFunctionDir> child = new LinkedList<>();
        // 过滤出直接下级
        List<MapFunctionDir> collectChild = dataList.stream().filter(funDir -> {
            return StringUtils.isNotBlank(funDir.getParentId()) && funDir.getParentId().equalsIgnoreCase(parentId);
        }).collect(Collectors.toList());
        // 递归过滤出子子下级
        for(MapFunctionDir mapFunctionDir : collectChild) {
            // 追加
            child.add(mapFunctionDir);
            // 递归子子节点
            child.addAll(this.filterChildFromList(dataList,mapFunctionDir.getId()));
        }
        return child;
    }



    @Override
    public List<MapFunctionDir> listTreeByFunctionIdAndUserId(PageData pd) {
        return mapFunctionDirMapper.listTreeByFunctionIdAndUserId(pd);
    }

    @Override
    public List<MapFunctionDir> getListTreeByFunctionIdAndUserId(MapFunctionDir mapFunctionDir) {
        List<MapFunctionDir> mapFunctionDirList = mapFunctionDirMapper.getListTreeByFunctionIdAndUserId(mapFunctionDir);
        return mapFunctionDirList;
    }

    @Override
    public List<MapFunctionDir> deleteByIds(String[] ids) {
        return mapFunctionDirMapper.deleteByIds(ids);
    }

    @Override
    public List<MapFunctionDir> verifyByName(String[] name, String parentId) {
        return mapFunctionDirMapper.verifyByName(name,parentId);
    }

    @Override
    public List<MapFunctionDir> getFunctionDirByRoleId(String functionCode, List<String> roleIds) {
        return mapFunctionDirMapper.getFunctionDirByRoleId(functionCode, roleIds);
    }

    @Override
    public String getNameByCode(String code) {
        LambdaQueryWrapper<MapFunctionDir> condition = new QueryWrapper().lambda();
        condition.select(MapFunctionDir::getName);
        condition.eq(MapFunctionDir::getCode, code);
        List<MapFunctionDir> list = list(condition);
        return CollectionUtils.isEmpty(list) ? null : list.get(0).getName();
    }

    @Override
    public MapFunctionDir getLayerEntityByCode(String code) {
        LambdaQueryWrapper<MapFunctionDir> condition = new QueryWrapper().lambda();
        condition.eq(MapFunctionDir::getCode, code);
        condition.eq(MapFunctionDir::getType, "2");
        List<MapFunctionDir> list = list(condition);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }
}
